package com.homedo.odin.solution.service.bizservice.mng;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.homedo.core.common.base.dto.Meta;
import com.homedo.core.common.exception.BizException;
import com.homedo.core.common.util.BeanUtils;
import com.homedo.core.common.util.CommonDataUtil;
import com.homedo.core.common.util.NumberHelper;
import com.homedo.odin.solution.contract.mng.SpecificationAuditReq;
import com.homedo.odin.solution.contract.mng.SpecificationDetailPriResp;
import com.homedo.odin.solution.contract.mng.SpecificationEditPriReq;
import com.homedo.odin.solution.contract.mng.SpecificationListPriResp;
import com.homedo.odin.solution.enumcode.basic.BusinessTypeEnum;
import com.homedo.odin.solution.enumcode.basic.CommonTypeDataEnum;
import com.homedo.odin.solution.enumcode.basic.DeleteEnum;
import com.homedo.odin.solution.enumcode.basic.ErrorCodeEnum;
import com.homedo.odin.solution.enumcode.basic.FromTypeEnum;
import com.homedo.odin.solution.enumcode.specification.SpecificationStatus;
import com.homedo.odin.solution.enumcode.user.PayStateEnum;
import com.homedo.odin.solution.model.dto.SpecificationListPriResponseBean;
import com.homedo.odin.solution.model.dto.UserPayRecordResponse;
import com.homedo.odin.solution.model.entity.CommonTypeData;
import com.homedo.odin.solution.model.entity.Specification;
import com.homedo.odin.solution.model.entity.UserPayOrder;
import com.homedo.odin.solution.service.AttachmentServiceImpl;
import com.homedo.odin.solution.service.CommonTypeDataServiceImpl;
import com.homedo.odin.solution.service.SpecificationServiceImpl;
import com.homedo.odin.solution.service.UserPayOrderServiceImpl;
import com.homedo.odin.solution.service.common.HomedoService;
import com.homedo.odin.solution.util.SpecificationBeansConvertUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author: zhaoxudong
 * @date: 2018/4/10 10:07
 * @Description:
 */
@Service
public class MngStandardsBizService {

    @Autowired
    SpecificationServiceImpl specificationService;
    @Autowired
    CommonTypeDataServiceImpl commonTypeDataService;
    @Autowired
    UserPayOrderServiceImpl userPayOrderService;
    @Autowired
    AttachmentServiceImpl attachmentService;
    @Autowired
    HomedoService homedoService;

    public SpecificationListPriResp list(String specificationName, Integer firstCassify, Integer secondClassify,
            Integer specificationStatus, Integer formType, Integer status, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<Specification> queryResult = new PageInfo<>(
                specificationService.querySpecificationListForPri(specificationName, firstCassify, secondClassify,
                        specificationStatus, formType, status));
        List<Specification> specificationList = queryResult.getList();
        List<SpecificationListPriResponseBean> resultList = new ArrayList<SpecificationListPriResponseBean>();
        if (CollectionUtils.isNotEmpty(specificationList)) {
            for (Specification specification : specificationList) {
                SpecificationListPriResponseBean specificationResponse = new SpecificationListPriResponseBean();
                SpecificationBeansConvertUtil.convert(specification, specificationResponse);
                CommonTypeData firstCommonTypeData = commonTypeDataService
                        .getCommonTypeDataById(specification.getFirstClassify());
                if (firstCommonTypeData != null) {
                    specificationResponse.setFirstClassifyStr(firstCommonTypeData.getName());
                }
                CommonTypeData secondCommonTypeData = commonTypeDataService
                        .getCommonTypeDataById(specification.getSecondClassify());
                if (secondCommonTypeData != null) {
                    specificationResponse.setSecondClassifyStr(secondCommonTypeData.getName());
                }
                List<UserPayOrder> orderList = userPayOrderService
                        .queryOrderByBusinessId(specification.getSpecificationId(),
                                BusinessTypeEnum.SPECIFICATION.getDbValue(), PayStateEnum.PAYCOMPLETE.getDbValue());
                List<UserPayRecordResponse> userPayRecordList = new ArrayList<UserPayRecordResponse>();
                if (CollectionUtils.isNotEmpty(orderList)) {
                    //添加下载记录
                    UserPayRecordResponse recordResponse = new UserPayRecordResponse();
                    for (UserPayOrder userPayOrder : orderList) {
                        recordResponse.setUserId(userPayOrder.getUid());
                        recordResponse.setAmount(userPayOrder.getAmount());
                        recordResponse.setPayTime(userPayOrder.getLastModifiedTime());
                        userPayRecordList.add(recordResponse);
                    }
                    //下载次数
                    specificationResponse.setPayCount(orderList.size());
                    if (specification.getFormType().intValue() == FromTypeEnum.BACK_UPLOAD.getDbValue()) {
                        specificationResponse
                                .setTotalAmount(specification.getCharges().multiply(new BigDecimal(orderList.size())));
                    } else {
                        specificationResponse.setTotalAmount(specification.getCharges().multiply(new BigDecimal(0.5))
                                .multiply(new BigDecimal(orderList.size())));
                    }
                } else {
                    specificationResponse.setPayCount(0);
                    specificationResponse.setTotalAmount(BigDecimal.ZERO);
                }
                specificationResponse.setUserPayRecordList(userPayRecordList);
                resultList.add(specificationResponse);
            }
        }
        SpecificationListPriResp resp = BeanUtils.transfrom(SpecificationListPriResp.class, queryResult);
        resp.setList(resultList);
        return resp;
    }

    public SpecificationDetailPriResp detail(Long specificationId) {
        if (!NumberHelper.validatePositive(specificationId)) {
            throw new BizException(Meta.CODE_451.getCode(), "参数不正确");
        }
        Specification specification = specificationService.getSpecification(specificationId);
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在!");
        }
        return BeanUtils.transfrom(SpecificationDetailPriResp.class, specification);
    }

    public void edit(SpecificationEditPriReq specificationEditBean) {
        Specification specification = specificationService.getSpecification(specificationEditBean.getSpecificationId());
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在");
        }
        //状态不为审核驳回状态 不允许编辑
        if (specification.getStatus().intValue() == SpecificationStatus.SHELVE.getDbValue()) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "该行业规范是上架状态中，无法修改！");
        }

        Integer firstClassify = specificationEditBean.getFirstClassify();//一级分类
        HashMap<String, String> hyghflMap = commonTypeDataService.getDataById(CommonTypeDataEnum.HYGFFL.getDbValue());
        if (!CommonDataUtil.validate(String.valueOf(firstClassify), hyghflMap)) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "行业规范一级分类不合法!");
        }
        Integer secondClassify = specificationEditBean.getSecondClassify();//二级分类
        if (!CommonDataUtil.validate(String.valueOf(secondClassify), hyghflMap)) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "行业规范二级分类不合法!");
        }
        SpecificationBeansConvertUtil.convert(specification, specificationEditBean);
        specification.setStatus(SpecificationStatus.AUDITSUCCESS.getDbValue());
        specificationService.updateSpecification(specification);
        //先删除原有方案附件
        attachmentService.delAttachmentByBusinessId(specification.getSpecificationId(),
                BusinessTypeEnum.SPECIFICATION.getDbValue());
        //增加方案附件详细信息
        String attachment = specification.getAttachment();
        attachmentService.addAttachment(attachment, specification.getSpecificationId(),
                BusinessTypeEnum.SPECIFICATION.getDbValue());
    }

    public void status(SpecificationAuditReq specificationAuditBean) {
        if (!ArrayUtils.contains(new int[]{SpecificationStatus.AUDITSUCCESS.getDbValue(),
                        SpecificationStatus.AUDITFAIL.getDbValue(), SpecificationStatus.DEL.getDbValue(),
                        SpecificationStatus.SHELVE.getDbValue(),
                        SpecificationStatus.UNSHELVE.getDbValue()},
                specificationAuditBean.getStatus())) {
            throw new BizException(Meta.CODE_451.getCode(), "操作状态不正确!");
        }

        //审核
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.AUDITFAIL.getDbValue() ||
                specificationAuditBean.getStatus().intValue() == SpecificationStatus.AUDITSUCCESS.getDbValue()) {
            audit(specificationAuditBean);
            return;
        }

        //上架
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.SHELVE.getDbValue()) {
            shelve(specificationAuditBean);
            return;
        }
        //下架
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.UNSHELVE.getDbValue()) {
            unShelve(specificationAuditBean);
            return;
        }
        //删除
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.DEL.getDbValue()) {
            del(specificationAuditBean);
        }

    }

    private void del(SpecificationAuditReq specificationAuditBean) {
        Specification specification = specificationService
                .getSpecification(specificationAuditBean.getSpecificationId());
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在!");
        }
        if (ArrayUtils.contains(new int[]{SpecificationStatus.SHELVE.getDbValue()}, specification.getStatus())) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "当前状态不支持该操作!");
        }
        //修改状态
        specificationService
                .auditSpecification(specificationAuditBean.getSpecificationId(), SpecificationStatus.DEL.getDbValue(),
                        null);
        //删除
        specificationService.updateDel(specificationAuditBean.getSpecificationId(), DeleteEnum.IS_DEL.getDbValue());
    }

    /**
     * 下架
     */
    private void unShelve(SpecificationAuditReq specificationAuditBean) {
        Specification specification = specificationService
                .getSpecification(specificationAuditBean.getSpecificationId());
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在!");
        }
        if (!ArrayUtils.contains(new int[]{SpecificationStatus.SHELVE.getDbValue()}, specification.getStatus())) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "当前状态不支持该操作!");
        }
        specificationService.auditSpecification(specificationAuditBean.getSpecificationId(),
                SpecificationStatus.UNSHELVE.getDbValue(), null);
    }

    /**
     * 上架
     */
    private void shelve(SpecificationAuditReq specificationAuditBean) {
        Specification specification = specificationService
                .getSpecification(specificationAuditBean.getSpecificationId());
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在!");
        }
        if (!ArrayUtils.contains(new int[]{SpecificationStatus.UNSHELVE.getDbValue(),
                SpecificationStatus.AUDITSUCCESS.getDbValue()}, specification.getStatus())) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "当前状态不支持该操作!");
        }
        //上架
        specification.setStatus(SpecificationStatus.SHELVE.getDbValue());
        specification.setShelveTime(new Date());
        specificationService.updateSpecification(specification);
    }

    /**
     * 修改审核状态
     */
    private void audit(SpecificationAuditReq specificationAuditBean) {
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.AUDITFAIL.getDbValue() &&
                StringUtils.isEmpty(specificationAuditBean.getAuditOpinion())) {
            throw new BizException(Meta.CODE_451.getCode(), "审核不通过时，审核意见不能为空!");
        }
        if (specificationAuditBean.getStatus().intValue() == SpecificationStatus.AUDITSUCCESS.getDbValue()) {
            specificationAuditBean.setAuditOpinion(null);
        }
        Specification specification = specificationService
                .getSpecification(specificationAuditBean.getSpecificationId());
        if (specification == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "该行业规范不存在!");
        }
        if (!ArrayUtils.contains(new int[]{SpecificationStatus.AUDITING.getDbValue()}, specification.getStatus())) {
            throw new BizException(ErrorCodeEnum.NotSupport.getDbValue(), "当前状态不支持该操作!");
        }
        specificationService
                .auditSpecification(specificationAuditBean.getSpecificationId(), specificationAuditBean.getStatus(),
                        specificationAuditBean.getAuditOpinion());
    }
}
